#include "bsp_port.h"

void bsp_uart_SendData(Bsp_Uart_t Uart, uint8_t *data, uint16_t datalen)
{
    USART_TypeDef *UART;
    uint32_t Channel;

    switch (Uart)
    {
    case BSP_UART1:
        UART = USART1;
        Channel = LL_DMA_CHANNEL_1;
        break;

    case BSP_UART2:
        UART = USART2;
        Channel = LL_DMA_CHANNEL_2;
        break;

        //    case BSP_UART3:
        //        UART = USART3;
        //        Channel = LL_DMA_CHANNEL_3;
        //        break;

        //    case BSP_UART4:
        //        UART = USART4;
        //        Channel = LL_DMA_CHANNEL_4;
        //        break;

    default:
        break;
    }

    LL_DMA_SetMemoryAddress(DMA1, Channel, (uint32_t)data);
    LL_DMA_SetDataLength(DMA1, Channel, datalen);
    LL_USART_EnableDMAReq_TX(UART);
    /* Enable DMA Channel Tx */
    LL_DMA_EnableChannel(DMA1, Channel);
}

volatile uint64_t TimestampCnt = 0;                 // 用来定时
#define ALARM_GET_TIME_CNT LL_TIM_GetCounter(TIM17) // 获取当前定时器的COUNT

// 重定向 printf();
int fputc(int ch, FILE *stream)
{
    while (!LL_USART_IsActiveFlag_TXE(USART1))
    {
        ;
    }
    LL_USART_TransmitData8(USART1, (uint8_t)ch);
    return ch;
}

/**@description: 获取当前软定时器的总计数值
 * @return {*}  当前软定时器的总计数值
 */
uint64_t get_Timestampus(void)
{
    return (uint64_t)TimestampCnt + ALARM_GET_TIME_CNT;
}

/**@description: 软定时器计时函数，需放在硬件定时中断中
 * @param {uint32_t} Time   定时器的一次定时计数值
 * @return {*}
 */
__INLINE void TimestampInc(uint32_t Time)
{
    TimestampCnt += Time;
}

void bsp_timeBase_Handler(void)
{
    TimestampInc(1000);
}

// 函数用于将 uint16_t 转换为字符串
char *uint16_to_str(uint16_t value, char *buffer, size_t bufferSize)
{
    snprintf(buffer, bufferSize, "%hu", value);
    return buffer;
}
// 定义延时函数
void bsp_Delay_us(uint32_t us)
{
    uint32_t ticks = us * (SystemCoreClock / 10000000); // 计算需要的SysTick时钟周期数
    SysTick->LOAD = ticks - 1;                          // 设置重载值
    SysTick->VAL = 0;                                   // 清空当前值
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;            // 开启SysTick计数器
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0)
        ;              // 等待计数完成
    SysTick->CTRL = 0; // 关闭SysTick计数器
}

// 看门狗喂狗
void bsp_IWDG_ReloadCounter(void)
{
    // LL_IWDG_ReloadCounter(IWDG); // 喂狗
}
